#pragma once
#include "d3dutil.h"
#include "LevelElement.h"
#include "Vertex.h"
#include <vector>
#include "triangle.h"

class NxActor;

class Skydome : public LevelElement
{
public:
	/**
	* Creates a new Skydome from a file name.
	* @param fileName the location of the Skydome.
	* @param nrOfColumns the number of columns in the Skydome.
	* @param nrOfRows the number of rows in the Skydome.
	* @param tileSize the scale factor for the tiles.
	* @param scaleHeight the scale factor for the height.
	* @param offset a value to add to the height.
	*/
	struct ScatteringInfo
	{
		D3DXVECTOR3 SunDirection;
		float		SunPos;
		float       HGgFunction;                   // g value in Henyey Greenstein approximation function
        float       InscatteringMultiplier;        // Multiply inscattering term with this factor
        float       BetaRayMultiplier;             // Multiply Rayleigh scattering coefficient with this factor
        float       BetaMieMultiplier;             // Multiply Mie scattering coefficient with this factor
        float       SunIntensity;                  // Current sun intensity
        float       Turbitity;        

		D3DXVECTOR3    BetaRay;
		D3DXVECTOR3    BetaDashRay;                    // Rayleigh angular scattering coefficient without phase term
		D3DXVECTOR3    BetaMie;                        // Mie total scattering coefficient
		D3DXVECTOR3    BetaDashMie;                    // Mie angular scattering coefficient without phase term
		D3DXVECTOR4    SunColorAndIntensity;           // Sun color and intensity packed for the shader
		D3DXVECTOR3    DiffuseConstant;
	};

	struct InitInfo
	{
		tstring Texture;
		int DomeN;
		float radiusHoriz;
		float radiusUp;
		D3DXVECTOR3 Position;
	};

	Skydome(Level *pLevel, InitInfo& info);
	/*
	* Destroys the Skydome object.
	*/
	virtual ~Skydome(void);

	virtual void Initialize(ContentManager *pContentManager);
	virtual void Tick(const InputState & refInputState){}
	virtual void Draw(const RenderContext* pRenderContext);
	virtual void DrawRefraction(const RenderContext* pRenderContext, D3DXPLANE refractionplane){}
	virtual void DrawReflection(const RenderContext* pRenderContext, D3DXMATRIX reflectionviewmatrix, D3DXPLANE reflectionplane);
	virtual void DrawShadowMap(const RenderContext* pRenderContext){}
	ScatteringInfo& GetScatterInformation() { return m_pScatterInfo; }

private:
	void CreateEffect(ContentManager *pContentManager);
	void GetEffectVariables(ID3D10Effect* pEffect);
	void BuildVertexBuffer();

	void DefineInputlayout();

	void CreateSkydome();	
			

	ID3D10InputLayout*			m_pVertexLayout;
	ID3D10Buffer*				m_pVertexBuffer;
	ID3D10Effect*				m_pDefaultEffect;
	ID3D10EffectTechnique*		m_pDefaultTechnique;
	//Textures
	ID3D10ShaderResourceView *	m_pTextureLow;
	ID3D10ShaderResourceView *	m_pPermTexture;
	ID3D10Texture2D* m_pPermMapVar;
	//Shader resources for textures

	ID3D10EffectMatrixVariable* m_pWorldViewProjectionVariable;
	ID3D10EffectMatrixVariable* m_pWorldVariable;

	ID3D10EffectVectorVariable* m_pEyePosVariable;
	ID3D10EffectVectorVariable* m_pSunDirectionVariable;
	ID3D10EffectVectorVariable* m_pBetaRPlusBetaMVariable;
	ID3D10EffectVectorVariable* m_pHCgVariable;
	ID3D10EffectVectorVariable* m_pBetaDahRVariable;
	ID3D10EffectVectorVariable* m_pBetaDashMVarable;
	ID3D10EffectVectorVariable* m_pOneOverBetaRVariable;
	ID3D10EffectVectorVariable* m_pMultiepliersVariable;
	ID3D10EffectVectorVariable* m_SunColorAndIntensity;


	ID3D10EffectShaderResourceVariable* m_pCubemapVariable;

	vector<VertexPosTex> m_VecVertices;


	D3DXMATRIX m_ReflectionViewMatrix;
	bool m_bReflection;
	InitInfo& m_IntInfo;

	////// poging 4
	ScatteringInfo m_pScatterInfo;
	unsigned int m_DomeN;
	float m_fRadiusHoriz;
    float m_fRadiusUp;
    int m_nThetaSides;
    int m_nPhiSides;			// Phi is angle from zenith, theta is azimuth angle.
    D3DXVECTOR3 m_vCenter;

    int mNumVertices;
	// -------------------------
	// Disabling default copy constructor and default assignment operator.
	// If you get a linker error from one of these functions, your class is internally trying to use them. This is
	// an error in your class, these declarations are deliberately made without implementation because they should never be used.
	// -------------------------
	Skydome(const Skydome& t);
	Skydome& operator=(const Skydome& t);
};
